package com.fcscs.cservice.client.main.reservation;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.IconButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.fcscs.core.common.MainPaginationSearchModel;
import com.fcscs.core.gwt.common.AsyncCallbackListener;
import com.fcscs.core.gwt.common.CoreConstants;
import com.fcscs.core.gwt.common.CoreEnums.SubmitType;
import com.fcscs.core.gwt.common.CoreUtil;
import com.fcscs.core.gwt.common.FormSubmitListener;
import com.fcscs.core.gwt.common.SearchExecutor;
import com.fcscs.core.gwt.common.ui.FcsFields.HighLightIconButton;
import com.fcscs.core.gwt.common.ui.FcsFormPanel;
import com.fcscs.core.gwt.common.ui.PagingSearchResultsPanel;
import com.fcscs.cservice.client.common.CServiceConstants;
import com.fcscs.cservice.client.common.controller.GuestProfileServiceController;
import com.fcscs.cservice.client.common.controller.ReservationServiceController;
import com.fcscs.cservice.client.common.model.reservation.ReservationViewModelData;
import com.fcscs.cservice.domain.model.CountryView;
import com.fcscs.cservice.domain.model.GuestProfileView;
import com.fcscs.cservice.domain.model.MessageView;
import com.fcscs.cservice.domain.model.RCView;
import com.fcscs.cservice.domain.model.ReservationConfView;
import com.fcscs.cservice.domain.model.ReservationView;
import com.fcscs.share.gwt.common.ShareGWTConstants;
import com.google.gwt.user.client.Event;

public class ReservationGrid extends PagingSearchResultsPanel<ReservationViewModelData, MainPaginationSearchModel> implements
		FormSubmitListener<ReservationView> {
	private static ReservationGrid INSTANCE;
	private GuestProfileDialog guestProfileDialog;
	private FlightInfoDialog flightInfoDialog;
	private RegistrationCardDialog rcDialog;
	private BaggageDialog baggageDialog;
	private MemberShipDialog memberShipDialog;
	private MessageDialog msgDialog;
	private ReservationConfView reservationConf;
	private List<CountryView> countryList;

	public static ReservationGrid getINSTANCE(String title,
			SearchExecutor<ReservationViewModelData, MainPaginationSearchModel> exe){
		if(null == INSTANCE){
			INSTANCE = new ReservationGrid(title, exe);
		}
		return INSTANCE;
	}
	
	public ReservationGrid(
			String title,
			SearchExecutor<ReservationViewModelData, MainPaginationSearchModel> exe) {
		super(title, exe, (Object[]) null);
		setCollapsible(false);
		//width*height
		setSize(950, 450);
	}

	@Override
	public void formSubmitCallBack(FcsFormPanel<ReservationView> form,
			SubmitType submitType) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected List<ColumnConfig> getColumnConfig(Object... params) {
		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
		ColumnConfig cc = CoreUtil.createNonSortableColumnConf(CServiceConstants.CONFIRMATION_NO,
				CServiceConstants.CSERVICE_CONSTANTS.confirmationNO(),90);
		columns.add(cc);
		columns.add(CoreUtil.createNonSortableColumnConf
				(ShareGWTConstants.ROOM,ShareGWTConstants.SHARE_GWT_CONSTANTS.room(), 50));
		cc = CoreUtil.createNonSortableColumnConf
	        (ShareGWTConstants.ROOM_STATUS,ShareGWTConstants.SHARE_GWT_CONSTANTS.roomStatus(), 80);
	    cc.setRenderer(new StautusRenderer());
	    columns.add(cc);
		
		cc = CoreUtil.createNonSortableColumnConf
		    (ShareGWTConstants.GUEST_NAME,ShareGWTConstants.SHARE_GWT_CONSTANTS.guestName(), 110);
		cc.setRenderer(new GridCellRenderer<ReservationViewModelData>(){
			@Override
			public Object render(ReservationViewModelData model,
					String property, ColumnData config, int rowIndex,
					int colIndex, ListStore<ReservationViewModelData> store,
					Grid<ReservationViewModelData> grid) {
				LayoutContainer hp = new LayoutContainer();
				hp.setId("ReservationGrid_show_RC_hp");
				hp.setLayout(new ColumnLayout());
				
                Label guestNameLabel = createShowGuestLabel(model);
                guestNameLabel.setId("ReservationGrid_show_RC_guestNameLabel");
                hp.add(guestNameLabel, new com.extjs.gxt.ui.client.widget.layout.ColumnData(60));
                
				HighLightIconButton rcButton = createShowRCButton(model);
				rcButton.setId("ReservationGrid_show_RC_button");
				rcButton.setStyleAttribute(CServiceConstants.CSS_MARGINLEFT, "20px");
				hp.add(rcButton);
				return hp;
			}
		});
		columns.add(cc);
		
		columns.add(CoreUtil.createNonSortableColumnConf
				(CServiceConstants.RESERVATION_STATUS,CServiceConstants.CSERVICE_CONSTANTS.reservationStatus(), 100));
		
		cc = CoreUtil.createNonSortableColumnConf(CServiceConstants.MEM_LV,
				CServiceConstants.CSERVICE_CONSTANTS.memLv(), 70);
		cc.setRenderer(new GridCellRenderer<ReservationViewModelData>() {
			@Override
			public Object render(ReservationViewModelData model,
					String property, ColumnData config, int rowIndex,
					int colIndex, ListStore<ReservationViewModelData> store,
					Grid<ReservationViewModelData> grid) {
				Label memLabel = createShowMemberShipLabel(model);
				memLabel.setId("ReservationGrid_memLabel");
		        return memLabel;
			}
		});
		columns.add(cc);
		
		columns.add(CoreUtil.createNonSortableColumnConf
				(CServiceConstants.MEM_NO,CServiceConstants.CSERVICE_CONSTANTS.membershipNo(), 60));
		cc = CoreUtil.createNonSortableColumnConf
            (ShareGWTConstants.ARRIVAL_DATE,ShareGWTConstants.SHARE_GWT_CONSTANTS.arrivalDate(), 80);
                cc.setRenderer(new GridCellRenderer<ReservationViewModelData>(){
	            @Override
	            public Object render(ReservationViewModelData model,
			        String property, ColumnData config, int rowIndex,
			        int colIndex, ListStore<ReservationViewModelData> store,
			        Grid<ReservationViewModelData> grid) {
	            Label arrivalDateLabel = createShowFlightInfoLabel(model);
	            arrivalDateLabel.setId("ReservationGrid_arrivalDateLabel");
		        return arrivalDateLabel;
	        }
        });
        columns.add(cc);
		
		
		columns.add(CoreUtil.createNonSortableColumnConf
				(ShareGWTConstants.ETA,ShareGWTConstants.SHARE_GWT_CONSTANTS.eta(), 40));
		columns.add(CoreUtil.createNonSortableColumnConf
				(ShareGWTConstants.DEPARTUAL_DATE,ShareGWTConstants.SHARE_GWT_CONSTANTS.departureDate(), 90));
		columns.add(CoreUtil.createNonSortableColumnConf
				(ShareGWTConstants.ETD,ShareGWTConstants.SHARE_GWT_CONSTANTS.etd(), 40));
		cc = CoreUtil.createNonSortableColumnConf
	        (CServiceConstants.BAGGAGE,CServiceConstants.CSERVICE_CONSTANTS.baggage(), 60);
	    cc.setRenderer(new GridCellRenderer<ReservationViewModelData>(){
		    @Override
		    public Object render(ReservationViewModelData model,
				    String property, ColumnData config, int rowIndex,
				    int colIndex, ListStore<ReservationViewModelData> store,
				    Grid<ReservationViewModelData> grid) {
			    HighLightIconButton ib = createShowBaggageButton(model);
			    ib.setId("ReservationGrid_show_baggage_button");
			    ib.setStyleAttribute(CServiceConstants.CSS_MARGINLEFT, "3px");
			    return ib;
		    }
	    });
	    columns.add(cc);
		cc = CoreUtil.createNonSortableColumnConf
            (ShareGWTConstants.MSG,ShareGWTConstants.SHARE_GWT_CONSTANTS.msg(), 60);
        cc.setRenderer(new GridCellRenderer<ReservationViewModelData>(){
	        @Override
	        public Object render(ReservationViewModelData model,
			        String property, ColumnData config, int rowIndex,
			        int colIndex, ListStore<ReservationViewModelData> store,
			        Grid<ReservationViewModelData> grid) {
		        HighLightIconButton ib = createShowMessageButton(model);
		        ib.setId("ReservationGrid_show_msg_button");
		        ib.setStyleAttribute(CServiceConstants.CSS_MARGINLEFT, "3px");
		        return ib;
	        }
        });
        columns.add(cc);
		return columns;
	}

	private HighLightIconButton createShowRCButton(final ReservationViewModelData model) {
		HighLightIconButton iconBtn = new HighLightIconButton(CServiceConstants.CSS_RC_READY_ICON,
				new SelectionListener<IconButtonEvent>() {
					@Override
					public void componentSelected(IconButtonEvent ce) {
						ReservationServiceController.getINSTANCE().getRCView(
							model.getEntity().getRcs().get(0).getRcId(),
							new AsyncCallbackListener<RCView>(){
								@Override
								public void onLogin(String username) {
									ReservationServiceController.getINSTANCE().getRCView(
										model.getEntity().getRcs().get(0).getRcId(), this);
								}
								@Override
								public void onFailure(Throwable caught) {
									MessageBox.alert(
											CoreConstants.CORE_MESSAGES.operation(
												CoreConstants.CORE_CONSTANTS.system(), 
												ShareGWTConstants.SHARE_GWT_CONSTANTS.error()),
											CoreConstants.CORE_CONSTANTS.systemError(), null);
								}
								@Override
								public void onSuccess(RCView result) {
									if (null != result) {
										rcDialog = RegistrationCardDialog.getInstance(
											new FormSubmitListener<RCView>() {
											@Override
											public void formSubmitCallBack(
												FcsFormPanel<RCView> form,
												SubmitType submitType) {}
											}, model, reservationConf, countryList, false);
										rcDialog.getFormPanel().updateForm(result);
										rcDialog.show();
									}
								}
							});
					}
				});
		iconBtn.setId("ReservationGrid_rc_iconBtn");
		iconBtn.setTitle(CServiceConstants.CSERVICE_CONSTANTS.showRC());
		iconBtn.setWidth(12);
		return iconBtn;
	}
	
	private HighLightIconButton createShowBaggageButton(final ReservationViewModelData model) {
		HighLightIconButton iconBtn = new HighLightIconButton(CServiceConstants.CSS_BAGGAGE_ICON,
				new SelectionListener<IconButtonEvent>() {
					@Override
					public void componentSelected(IconButtonEvent ce) {
						if (model.getEntity().getBaggageNumber() != null && !model.getEntity().getBaggageNumber().trim().isEmpty()) {
							baggageDialog = BaggageDialog.getInstance();
							baggageDialog.getFormPanel().updateForm(model.getEntity());
							baggageDialog.show();
						}else{
							MessageBox.alert(null,
									CServiceConstants.CSERVICE_MESSAGES.thereIsNo(CServiceConstants.CSERVICE_CONSTANTS.baggage()), 
									null);
						}
					}
				});
		iconBtn.setTitle(CServiceConstants.CSERVICE_CONSTANTS.showBaggage());
		return iconBtn;
	}
	
	private HighLightIconButton createShowMessageButton(final ReservationViewModelData model) {
		HighLightIconButton iconBtn = new HighLightIconButton(CServiceConstants.CSS_MSG_TEMPLATE_SM_ICON,
				new SelectionListener<IconButtonEvent>() {
					@Override
					public void componentSelected(IconButtonEvent ce) {
						ReservationServiceController.getINSTANCE().getMessages(
							model.getEntity().getReservationViewId(), 
							new AsyncCallbackListener<List<MessageView>>(){
								@Override
								public void onLogin(String username) {
									ReservationServiceController.getINSTANCE().getMessages(
											model.getEntity().getReservationViewId(),this);
								}

								@Override
								public void onFailure(Throwable caught) {
									MessageBox.alert(
										CoreConstants.CORE_MESSAGES.operation(
											CoreConstants.CORE_CONSTANTS.system(), 
											ShareGWTConstants.SHARE_GWT_CONSTANTS.error()),
										CoreConstants.CORE_CONSTANTS.systemError(), null);
								}

								@Override
								public void onSuccess(List<MessageView> result) {
									if (null != result) {
										if (result.size() > 0) {
											msgDialog = MessageDialog.getInstance(null, result);
											msgDialog.getFormPanel().updateForm(model.getEntity());
											msgDialog.show();
										}else{
											MessageBox.alert(null,
												CServiceConstants.CSERVICE_MESSAGES.thereIsNo(CoreConstants.CORE_CONSTANTS.message()), 
												null);
										}
									}else{
										MessageBox.alert(
												CoreConstants.CORE_MESSAGES.operation(
													CoreConstants.CORE_CONSTANTS.system(), 
													ShareGWTConstants.SHARE_GWT_CONSTANTS.error()),
												CoreConstants.CORE_CONSTANTS.systemError(), null);
									}
								}
							});
					}
				});
		iconBtn.setTitle(CServiceConstants.CSERVICE_CONSTANTS.showMessage());
		return iconBtn;
	}
	
	private Label createShowGuestLabel(final ReservationViewModelData model) {
		Label guestNameLabel = new Label();
		String name = model.getEntity().getGuestFirstName() 
		              + "," + model.getEntity().getGuestLastName();
		
		guestNameLabel.setText("<U>" + name + "</U>");
		guestNameLabel.sinkEvents(Event.ONCLICK);
		guestNameLabel.addListener(Events.OnClick, new Listener<BaseEvent>(){
			@Override
			public void handleEvent(BaseEvent be) {

				GuestProfileServiceController.getINSTANCE().getGuestProfileView(
					model.getEntity().getGuestProfileId(), 
					new AsyncCallbackListener<GuestProfileView>(){
						@Override
						public void onLogin(String username) {
							GuestProfileServiceController.getINSTANCE().getGuestProfileView(
									model.getEntity().getGuestProfileId(),this);
						}
						@Override
						public void onFailure(Throwable caught) {
							MessageBox.alert(CoreConstants.CORE_MESSAGES.operation(CoreConstants.CORE_CONSTANTS.system(), ShareGWTConstants.SHARE_GWT_CONSTANTS.error()),
									CoreConstants.CORE_CONSTANTS.systemError(), null);
							caught.printStackTrace();
						}
						@Override
						public void onSuccess(GuestProfileView result) {
							guestProfileDialog = GuestProfileDialog.getInstance(new FormSubmitListener<GuestProfileView>(){
								@Override
								public void formSubmitCallBack(
										FcsFormPanel<GuestProfileView> form,
										SubmitType submitType) {
									
								}
							}, model, reservationConf, countryList);
							guestProfileDialog.getFormPanel().updateForm(result);
							guestProfileDialog.show();
						}
					});
			}
		});
		return guestNameLabel;
	}
	
	private Label createShowFlightInfoLabel(final ReservationViewModelData model) {
		Label arrivalDateLabel = new Label();
		arrivalDateLabel.setText("<U>" + CServiceConstants.DATE_FORMAT1.format(model.getEntity().getArrivalDateTime()) +"</U>");
		arrivalDateLabel.setWidth(75);
		arrivalDateLabel.sinkEvents(Event.ONCLICK);
		arrivalDateLabel.addListener(Events.OnClick, new Listener<BaseEvent>(){
			@Override
			public void handleEvent(BaseEvent be) {
				flightInfoDialog = FlightInfoDialog.getInstance(new FormSubmitListener<ReservationView>(){
					@Override
					public void formSubmitCallBack(
							FcsFormPanel<ReservationView> form,
							SubmitType submitType) {
					}
				});
				flightInfoDialog.getFormPanel().updateForm(model.getEntity());
				flightInfoDialog.show();
			}
		});
		return arrivalDateLabel;
	}
	
	private Label createShowMemberShipLabel(final ReservationViewModelData model) {
		Label memShipLabel = new Label();
		if (model.getEntity().getMemberships() != null && model.getEntity().getMemberships().size() > 0) {
			memShipLabel.setText("<U>"
					+ model.getEntity().getMemberships().get(0).getLevel()
					+ "</U>");
		}else{
			memShipLabel.setText("");
		}
		memShipLabel.setWidth(50);
		memShipLabel.sinkEvents(Event.ONCLICK);
		memShipLabel.addListener(Events.OnClick, new Listener<BaseEvent>(){
			@Override
			public void handleEvent(BaseEvent be) {
				if (model.getEntity().getMemberships() != null && model.getEntity().getMemberships().size() > 0) {
					memberShipDialog = MemberShipDialog.getINSTANCE(CServiceConstants.CSERVICE_CONSTANTS.memberInfo(),
							model.getEntity().getMemberships(), model.getEntity().getGuestFirstName() + ","
									+ model.getEntity().getGuestLastName());
					memberShipDialog.getFormPanel().updateForm(model.getEntity().getMemberships().get(0));
					memberShipDialog.show();
				}
			}
		});
		return memShipLabel;
	}
	
	private class StautusRenderer implements GridCellRenderer<ReservationViewModelData>{

		@Override
		public Object render(ReservationViewModelData model, String property,
				ColumnData config, int rowIndex, int colIndex,
				ListStore<ReservationViewModelData> store,
				Grid<ReservationViewModelData> grid) {
			String color = null;
			color ="#" + /*Integer.toHexString(Integer.parseInt(*/model.getEntity().getRoomStatusColor();//);
			return color == null ? model.getEntity().getRoomStatus() : "<div align='center' style='background-color:"+color+"'>"+model.getEntity().getRoomStatus()+"</div>";			
		}
	}

	public void setReservationConf(ReservationConfView reservationConf) {
		this.reservationConf = reservationConf;
	}

	public void setCountryList(List<CountryView> countryList) {
		this.countryList = countryList;
	}
}
